package kassiopeia.plugin;

import java.io.Serializable;

public abstract class Plugin implements PluginLifecycle {

    public static final String PLUGIN_DESCRIPTOR_PATH = "META-INF/plugin.xml";

    private Context context;

    public Plugin() {}

    public Plugin(Context context) {
        this.context = context;
    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    @Override
    public void beforeTask() {}

    @Override
    public void afterTask() {}

    protected <T extends Serializable> T getNotNullableEventBody(Event event, Class<T> bodyClass) {
        Object eventBody = event.getBody();

        assertNotNull(eventBody, "Expected body object, but found null.");

        String expected = bodyClass.getCanonicalName();
        String actual = eventBody.getClass().getCanonicalName();

        assertType(eventBody, bodyClass, "Unexpected event body type. Expecting: " + expected + ", but found: " + actual);

        return bodyClass.cast(eventBody);
    }

    protected <T extends Serializable> T getNotNullableEventHeader(Event event, String headerName, Class<T> headerClass) {
        Object header = event.getHeader(headerName);

        assertNotNull(header, "Missing expected header: " + headerName);

        String expected = headerClass.getCanonicalName();
        String actual = header.getClass().getCanonicalName();

        assertType(header, headerClass, "Unexpected event header type. Expecting: " + expected + ", but found: " + actual);

        return headerClass.cast(header);
    }

    private void assertNotNull(Object object, String exceptionMessage) {
        if(object == null) {
            throw new PluginException(exceptionMessage);
        }
    }

    private void assertType(Object object, Class<?> clazz, String exceptionMessage) {
        if(!clazz.isInstance(object)) {
            throw new PluginException(exceptionMessage);
        }
    }
}
